package cbs.jdtag.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.MessageFormat;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;

/**
 * A simple log formatter that adapts the default output of log4j.
 *
 */
public class LogFormatter extends Formatter {

	// the system dependent directory separator
	private static final String LINE_SEPARATOR = System.getProperty("line.separator");
	
	// message formatter to show something like '21.09.2011 16:10:25' in the log
	private final MessageFormat messageFormatter = new MessageFormat("{0,date} {0,time}");
	
	@Override
	public final String format(final LogRecord record) {
		final StringBuffer result = new StringBuffer();
		
		// append log level, date and time
		result.append(record.getLevel().getLocalizedName());
		result.append(" ");
		result.append(messageFormatter.format(new Object[]{record.getMillis()}));
		result.append(" ");
		
		// append class
		if (record.getSourceClassName() != null) {	
			result.append(record.getSourceClassName());
		}
		else {
			result.append(record.getLoggerName());
		}
		
		// append method
		if (record.getSourceMethodName() != null) {	
			result.append(" ");
			result.append(record.getSourceMethodName());
		}
		
		// append message
		result.append(": ");
		result.append(formatMessage(record));
		
		// append throwable, if any
		if (record.getThrown() != null) {
			final StringWriter sw = new StringWriter();
			final PrintWriter pw = new PrintWriter(sw);
			record.getThrown().printStackTrace(pw);
			pw.flush();
			sw.flush();
			
			result.append(LINE_SEPARATOR);
			result.append(sw.toString());
			
			pw.close();
			try {
				sw.close();
			}
			catch (final IOException e) {
				// Siehe Java-API:
				// "Closing a StringWriter has no effect. The methods in this
			    // class can be called after the stream has been closed without generating
			    // an IOException."
			}
		}
		
		// add line feed
		result.append(LINE_SEPARATOR);
		
		return result.toString();
	}
}
